package com.fingard.dsp.bank.directbank.jytpay01;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;

import com.fingard.constant.Format;
import com.fingard.dsp.bank.directConfig.ActSetItem;
import com.fingard.dsp.bank.directbank.FailCode;
import com.fingard.dsp.bank.directbank.PaymentState;
import com.fingard.dsp.bank.directbank.bankInterface.IRealTime;
import com.fingard.dsp.bank.reqrespobj.single.ReqQrySingle;
import com.fingard.dsp.bank.reqrespobj.single.ReqSingle;
import com.fingard.dsp.bank.reqrespobj.single.RetAtsSingle;
import com.fingard.dsp.bank.reqrespobj.single.detail.RetAtsSglDetail;
import com.fingard.net.ConnState;
import com.fingard.text.StringHelper;
import com.fingard.xml.XmlTextReader;
import com.fingard.xml.XmlTextWriter;

/**
 *  金运通单笔实时代扣  
 *  	    --  单笔代收TC1001 
 *         --  用于单笔代收企业或个人的银行账户资金，企业暂时只支持民生银行的对公账户
 *         --  需要代收用户银行卡（借记卡）的资金时使用
 */
public class JYTPAY01RealTime extends JYTPAY01Base implements IRealTime {
	/**
	 * 单笔实时代扣交易提交
	 */
	public RetAtsSingle d_9108_RealTimeRec(ReqSingle p_req9108)	throws Exception {
		RetAtsSingle retAts = new RetAtsSingle(p_req9108.reqHeader);
		RetAtsSglDetail tmpRetDetail = new RetAtsSglDetail();
		
		try {
			ActSetItem actItem = getBankConfig().getActSetItem(p_req9108.singleDetail.recAct, "");
			if (actItem == null) {
				tmpRetDetail.respCode = "0";
				tmpRetDetail.respInfo = "未找到账号"+p_req9108.singleDetail.recAct+"对应的商户配置信息";
				tmpRetDetail.transAmt = p_req9108.singleDetail.payAmount;
				tmpRetDetail.reqSeqID = p_req9108.singleDetail.askNumber;
				tmpRetDetail.transState = PaymentState.FAIL_Payment;
				tmpRetDetail.payInfoCode = "E9981";
				
				retAts.writeRetDetail(tmpRetDetail);
				return retAts;
			}
			
			JYTPAY01Header bankHeader = new JYTPAY01Header();
			bankHeader.tran_code = "TC1001";
			bankHeader.tran_flowid = actItem.merchantId + Format.DateTime14Format.format(new Date()) + String.format("%06d", new Random().nextInt(999999));
			
			XmlTextWriter xmlWriter = new XmlTextWriter();
			writeCommonHeader(xmlWriter, bankHeader, actItem);
			
			xmlWriter.writeStartElement("body");
			xmlWriter.writeElementString("mer_viral_acct", "");// 虚拟账号
			xmlWriter.writeElementString("agrt_no", "");// 协议号
			xmlWriter.writeElementString("bank_name", p_req9108.singleDetail.payBankName);// 银行名称
			xmlWriter.writeElementString("account_no", p_req9108.singleDetail.payAct);// 银行账号
			xmlWriter.writeElementString("account_name", p_req9108.singleDetail.payName);// 银行账户名称
			
			// 账户类型   00 - 对私； 01 - 对公(暂不支持)； 
			if (p_req9108.singleDetail.isPrivate.equals("1")) {
				xmlWriter.writeElementString("account_type", "00");
			}else {
				xmlWriter.writeElementString("account_type", "01");
			}
			
			xmlWriter.writeElementString("brach_bank_province", "");// 省
			xmlWriter.writeElementString("brach_bank_city", "");// 市
			xmlWriter.writeElementString("brach_bank_name", "");// 开户行名称
			xmlWriter.writeElementString("tran_amt", p_req9108.singleDetail.payAmount);// 交易金额 保留两位小数，整数最大位13位
			xmlWriter.writeElementString("currency", convertCurToBank(p_req9108.singleDetail.payCur));// 币种
			xmlWriter.writeElementString("bsn_code", getBankConfig().getMapValueByKey("payUseMapping", "0"));// 代收业务类型
			xmlWriter.writeElementString("cert_type", convertCertTypeToBank(p_req9108.singleDetail.certType));//证件类型
			xmlWriter.writeElementString("cert_no", p_req9108.singleDetail.certNum);//证件号码
			xmlWriter.writeElementString("mobile", p_req9108.singleDetail.cellPhone);
			xmlWriter.writeElementString("remark", "");// 摘要信息
			xmlWriter.writeElementString("reserve", "");// 预留字段
			xmlWriter.writeEndElement();
			xmlWriter.writeEndDocument();
			
			// 报文明文
			WriteBankLogLn2("金运通单笔实时代扣请求报文: \n" + xmlWriter.toXmlString());
			
			// 加密报文并生成签名
			String[] postStr = encryptAndSign(xmlWriter.toXmlString(),actItem);
			
			// http请求数据
			Map<String,String> postParams = new HashMap<String,String>();
			postParams.put("merchant_id", actItem.merchantId);
			postParams.put("xml_enc", postStr[0]);// 加密报文
			postParams.put("key_enc", postStr[1]);// 加密密钥
			postParams.put("sign", postStr[2]);// 签名
			
			// 发送金运通
			String[] tmpStrRet = sendToBank("unifiedPay",postParams);
			
			// 解析金运通返回
			if (tmpStrRet[0].length() == 0) {
				// http返回数据
				WriteBankLogLn2("金运通http返回数据: \n" + tmpStrRet[1]);
				
				String[] respHttpStr = tmpStrRet[1].split("&");
				String hexXmlEnc = respHttpStr[1].split("=")[1].replace("\"", "");// 返回XML密文
				String hexKeyEnc = respHttpStr[2].split("=")[1].replace("\"", "");// 会话密钥密文
				String hexSign = respHttpStr[3].split("=")[1].replace("\"", "");// 签名
				
				// 解密验签
				String[] tmpRespStr = decryptAndVeriSign(hexXmlEnc, hexKeyEnc, hexSign,actItem);
				String respXml = tmpRespStr[0];// 返回报文明文
				String respSign = tmpRespStr[1];// 验签结果
				
				// 验签处理
				if (respSign.equals("1")) {
					// 返回报文
					WriteBankLogStep3(respXml);
					
					// 解析报文
					StringBuilder tmpSbMsg = new StringBuilder();
					XmlTextReader tmpBkReader = loadBankRespXmlReader(respXml, tmpSbMsg);
					
					if(tmpBkReader != null){
						String tmpRespCode = tmpBkReader.getFirstText("/message/head/resp_code");
						String tmpRespInfo = tmpBkReader.getFirstText("/message/head/resp_desc");
						
						if (tmpRespCode.equals("S0000000")) {
							tmpRetDetail.respCode = "0";
							tmpRetDetail.respInfo = tmpRespInfo;
							tmpRetDetail.reqSeqID = p_req9108.singleDetail.askNumber;
							tmpRetDetail.transAmt = p_req9108.singleDetail.payAmount;
							tmpRetDetail.transState = tmpRespCode + "+" + tmpBkReader.getFirstText("/message/body/tran_state");
							tmpRetDetail.payInfoCode = tmpRespCode;
						}else {
							tmpRetDetail.respCode = "-1";
							tmpRetDetail.respInfo = tmpRespInfo;
						}
					}else{
						tmpRetDetail.respCode = "-1";
						tmpRetDetail.respInfo = tmpSbMsg.toString();
					}
				} else {
					tmpRetDetail.respCode = "-1";
					tmpRetDetail.respInfo = "验证签名失败!";
				}
			} else if (tmpStrRet[0].equals(ConnState.FAIL) || tmpStrRet[0].equals(FailCode.E9981)) {
				tmpRetDetail.respCode = "0";
				tmpRetDetail.respInfo = tmpStrRet[1];
				tmpRetDetail.reqSeqID = p_req9108.singleDetail.askNumber;
				tmpRetDetail.transAmt = p_req9108.singleDetail.payAmount;
				tmpRetDetail.transState = PaymentState.FAIL_Payment;
				tmpRetDetail.payInfoCode = tmpStrRet[0];
			} else {
				tmpRetDetail.respCode = "-1";
				tmpRetDetail.respInfo = tmpStrRet[1];
			}
		} catch (Exception e) {
			tmpRetDetail.respCode = "-1";
			tmpRetDetail.respInfo = e.toString();
			e.printStackTrace();
		}
		
		if (tmpRetDetail.respCode.equals("-1") && StringHelper.isNullOrEmpty(tmpRetDetail.reqSeqID)) {
			tmpRetDetail.reqSeqID = p_req9108.singleDetail.askNumber;
		}
		
		retAts.writeRetDetail(tmpRetDetail);
		return retAts;
	}

	/**
	 * 单笔实时代扣交易状态查询
	 * 			--  单笔代收结果查询TC2001
	 * 			--  用于商户单笔查询单笔代收交易的交易结果状态
	 * 			--	单笔代收交易返回的交易状态未确定时使用
	 */
	public RetAtsSingle d_9144_QryRealTimeRec(ReqQrySingle p_req9144) throws Exception {
		RetAtsSingle retAts = new RetAtsSingle(p_req9144.reqHeader);
		RetAtsSglDetail tmpRetDetail = new RetAtsSglDetail();
		
		try {
			ActSetItem actItem = getBankConfig().getActSetItem(p_req9144.recAct, "");
			if (actItem == null) {
				tmpRetDetail.respCode = "0";
				tmpRetDetail.respInfo = "未找到账号" + p_req9144.recAct + "对应的商户配置信息";
				tmpRetDetail.reqSeqID = p_req9144.askNumber;
				tmpRetDetail.transAmt = p_req9144.payAmount;
				tmpRetDetail.transState = PaymentState.FAIL_Payment;
				tmpRetDetail.payInfoCode = FailCode.E9981;
				
				retAts.writeRetDetail(tmpRetDetail);
				return retAts;
			}
			
			JYTPAY01Header bankHeader = new JYTPAY01Header();
			bankHeader.tran_code = "TC2001";
			bankHeader.tran_flowid = actItem.merchantId + Format.DateTime14Format.format(new Date()) + String.format("%06d", new Random().nextInt(999999));

			XmlTextWriter xmlWriter = new XmlTextWriter();
			writeCommonHeader(xmlWriter, bankHeader, actItem);
			
			xmlWriter.writeStartElement("body");
			xmlWriter.writeElementString("ori_tran_flowid", p_req9144.askNumber);// 商户代收原交易流水号
			xmlWriter.writeEndElement();
			xmlWriter.writeEndDocument();
				
			// 报文明文
			WriteBankLogLn2("金运通单笔实时代扣状态查询请求报文: \n" + xmlWriter.toXmlString());
			
			// 加密报文并生成签名
			String[] postStr = encryptAndSign(xmlWriter.toXmlString(),actItem);
			
			// http请求数据
			Map<String,String> postParams = new HashMap<String,String>();
			postParams.put("merchant_id", actItem.merchantId);
			postParams.put("xml_enc", postStr[0]);// 加密报文
			postParams.put("key_enc", postStr[1]);// 加密密钥
			postParams.put("sign", postStr[2]);// 签名
			
			// 发送金运通
			String[] tmpStrRet = sendToBank("unifiedPay",postParams);
			
			// 解析金运通http返回
			if(tmpStrRet[0].length() == 0) {
				// http返回数据
				WriteBankLogLn2("金运通http返回数据: \n" + tmpStrRet[1]);
				
				String[] respHttpStr = tmpStrRet[1].split("&");
				String hexXmlEnc = respHttpStr[1].split("=")[1].replace("\"", "");// 报文密文
				String hexKeyEnc = respHttpStr[2].split("=")[1].replace("\"", "");// 密钥密文
				String hexSign = respHttpStr[3].split("=")[1].replace("\"", "");// 签名
				
				// 解密验签
				String[] tmpRespStr = decryptAndVeriSign(hexXmlEnc, hexKeyEnc, hexSign,actItem);
				String respXml = tmpRespStr[0];// 解密后报文
				String respSign = tmpRespStr[1];// 验签结果
				
				// 验签处理
				if (respSign.equals("1")) {
					// 返回报文
					WriteBankLogStep3(respXml);
					
					// 解析报文
					StringBuilder tmpSbMsg = new StringBuilder();
					XmlTextReader tmpBkReader = loadBankRespXmlReader(respXml, tmpSbMsg);
					
					if(tmpBkReader != null){
						String tmpRespCode = tmpBkReader.getFirstText("/message/head/resp_code");
						String tmpRespInfo = tmpBkReader.getFirstText("/message/head/resp_desc");
						
						if (tmpRespCode.equals("S0000000")) {
							String tranRespCode = tmpBkReader.getFirstText("/message/body/tran_resp_code");
							
							tmpRetDetail.respCode = "0";
							tmpRetDetail.respInfo = tmpRespInfo;
							tmpRetDetail.reqSeqID = p_req9144.askNumber;
							tmpRetDetail.transAmt = p_req9144.payAmount;
							tmpRetDetail.transState = tranRespCode + "+" + tmpBkReader.getFirstText("/message/body/tran_state");
							tmpRetDetail.payInfoCode = tranRespCode;
					   }else {
							tmpRetDetail.respCode = "-1";
							tmpRetDetail.respInfo = tmpRespInfo;
					   }
					}else{
						tmpRetDetail.respCode = "-1";
						tmpRetDetail.respInfo = tmpSbMsg.toString();
					}
				} else {
					tmpRetDetail.respCode = "-1";
					tmpRetDetail.respInfo = "验证签名失败!";
				}
		    } else {
				tmpRetDetail.respCode = "-1";
				tmpRetDetail.respInfo = tmpStrRet[1];
			}
		} catch (Exception e) {
			tmpRetDetail.respCode = "-1";
			tmpRetDetail.respInfo = e.getMessage();
			e.printStackTrace();
		}
		
		if (tmpRetDetail.respCode.equals("-1") && StringHelper.isNullOrEmpty(tmpRetDetail.reqSeqID)) {
			tmpRetDetail.reqSeqID = p_req9144.askNumber;
		}
		
		retAts.writeRetDetail(tmpRetDetail);
		return retAts;
	}
}
